const User = require('./User');
const crypto = require('crypto');

class AuthService {
    constructor(dbManager) {
        this.db = dbManager;
    }

    // Register new user
    async register(username, password, role = 'user') {
        try {
            // Check if user already exists
            const existingUser = await this.db.getUserByUsername(username);
            if (existingUser) {
                throw new Error('Username already exists');
            }

            // Create new user
            const userData = await this.db.createUser(username, password, role);
            return User.fromDB(userData);
        } catch (error) {
            throw new Error(`Registration failed: ${error.message}`);
        }
    }

    // Login user
    async login(username, password) {
        try {
            // Get user from database
            const userData = await this.db.getUserByUsername(username);
            if (!userData) {
                throw new Error('Invalid username or password');
            }

            // Create user instance
            const user = User.fromDB(userData);

            // Verify password
            const isValidPassword = await user.verifyPassword(password);
            if (!isValidPassword) {
                throw new Error('Invalid username or password');
            }

            // Create session
            const sessionId = this.generateSessionId();
            const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours

            await this.db.createSession(sessionId, user.id, expiresAt);

            return {
                user: user.toJSON(),
                sessionId,
                expiresAt
            };
        } catch (error) {
            throw new Error(`Login failed: ${error.message}`);
        }
    }

    // Logout user
    async logout(sessionId) {
        try {
            await this.db.deleteSession(sessionId);
            return true;
        } catch (error) {
            throw new Error(`Logout failed: ${error.message}`);
        }
    }

    // Validate session
    async validateSession(sessionId) {
        try {
            console.log('AuthService - Validating session:', sessionId);
            const session = await this.db.getSession(sessionId);
            console.log('AuthService - Session from database:', session);
            
            if (!session) {
                return null;
            }

            return {
                user: {
                    id: session.userId,
                    username: session.username,
                    role: session.role
                },
                sessionId: session.id,
                expiresAt: session.expiresAt
            };
        } catch (error) {
            console.error('AuthService - Session validation error:', error);
            return null;
        }
    }

    // Generate session ID
    generateSessionId() {
        return crypto.randomBytes(32).toString('hex');
    }

    // Create default admin user if not exists
    async createDefaultAdmin() {
        try {
            const adminExists = await this.db.getUserByUsername('admin');
            if (!adminExists) {
                await this.register('admin', 'admin123', 'admin');
                console.log('Default admin user created');
            }
        } catch (error) {
            console.error('Failed to create default admin user:', error.message);
        }
    }

    // Get all users (admin only)
    async getAllUsers() {
        try {
            return await this.db.getAllUsers();
        } catch (error) {
            throw new Error(`Failed to get users: ${error.message}`);
        }
    }

    // Update user role (admin only)
    async updateUserRole(userId, role) {
        try {
            const success = await this.db.updateUserRole(userId, role);
            if (!success) {
                throw new Error('User not found');
            }
            return true;
        } catch (error) {
            throw new Error(`Failed to update user role: ${error.message}`);
        }
    }

    // Delete user (admin only)
    async deleteUser(userId) {
        try {
            const success = await this.db.deleteUser(userId);
            if (!success) {
                throw new Error('User not found');
            }
            return true;
        } catch (error) {
            throw new Error(`Failed to delete user: ${error.message}`);
        }
    }
}

module.exports = AuthService;